'Copyright 2019 Esri

'Licensed under the Apache License, Version 2.0 (the "License");
'you may not use this file except in compliance with the License.
'You may obtain a copy of the License at

'    http://www.apache.org/licenses/LICENSE-2.0

'Unless required by applicable law or agreed to in writing, software
'distributed under the License is distributed on an "AS IS" BASIS,
'WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

'See the License for the specific language governing permissions and
'limitations under the License.
Option Explicit On
Imports ESRI.ArcGIS.esriSystem
Imports System
Imports System.Collections.Generic
Imports System.Diagnostics


Namespace DemoITableBinding

    'FILE AUTOMATICALLY GENERATED BY ESRI LICENSE INITIALIZATION ADDIN
    'YOU SHOULD NOT NORMALLY EDIT OR REMOVE THIS FILE FROM THE PROJECT

    Friend Class LicenseInitializer

        Private m_AoInit As IAoInitialize = New AoInitializeClass()
#Region "Private members"
        Private Const MessageNoLicensesRequested As String = "Product: No licenses were requested"
        Private Const MessageProductAvailable As String = "Product: {0}: Available"
        Private Const MessageProductNotLicensed As String = "Product: {0}: Not Licensed"
        Private Const MessageExtensionAvailable As String = " Extension: {0}: Available"
        Private Const MessageExtensionNotLicensed As String = " Extension: {0}: Not Licensed"
        Private Const MessageExtensionFailed As String = " Extension: {0}: Failed"
        Private Const MessageExtensionUnavailable As String = " Extension: {0}: Unavailable"

        Private m_hasShutDown As Boolean = False
        Private m_hasInitializeProduct As Boolean = False

        Private m_requestedProducts As List(Of Integer)
        Private m_requestedExtensions As List(Of esriLicenseExtensionCode)
        Private m_productStatus As Dictionary(Of esriLicenseProductCode, esriLicenseStatus) = New Dictionary(Of esriLicenseProductCode, esriLicenseStatus)()
        Private m_extensionStatus As Dictionary(Of esriLicenseExtensionCode, esriLicenseStatus) = New Dictionary(Of esriLicenseExtensionCode, esriLicenseStatus)()

        Private m_productCheckOrdering As Boolean = True 'default from low to high
#End Region

        Public Function InitializeApplication(ByVal productCodes As esriLicenseProductCode(), ByVal extensionLics() As esriLicenseExtensionCode) As Boolean
            'Cache product codes by enum int so can be sorted without custom sorter
            m_requestedProducts = New List(Of Integer)()
            For Each code As esriLicenseProductCode In productCodes
                Dim requestCodeNum As Integer = CInt(code)
                If Not m_requestedProducts.Contains(requestCodeNum) Then
                    m_requestedProducts.Add(requestCodeNum)
                End If
            Next

            AddExtensions(extensionLics)
            Return Initialize()
        End Function

        ''' <summary>
        ''' A summary of the status of product and extensions initialization.
        ''' </summary>
        Public Function LicenseMessage() As String
            Dim prodStatus As String = String.Empty
            Dim licenseInfo As ILicenseInformation = CType(m_AoInit, ILicenseInformation)
            If m_productStatus Is Nothing OrElse m_productStatus.Count = 0 Then
                prodStatus = MessageNoLicensesRequested + Environment.NewLine
            ElseIf (m_productStatus.ContainsValue(esriLicenseStatus.esriLicenseAlreadyInitialized) _
                Or m_productStatus.ContainsValue(esriLicenseStatus.esriLicenseCheckedOut)) Then

                prodStatus = ReportInformation(licenseInfo, _
                        m_AoInit.InitializedProduct(), esriLicenseStatus.esriLicenseCheckedOut) _
                        + Environment.NewLine
            Else
                'Failed...
                For Each item As KeyValuePair(Of esriLicenseProductCode, esriLicenseStatus) In m_productStatus
                    prodStatus += ReportInformation(licenseInfo, item.Key, item.Value) + Environment.NewLine
                Next
            End If

            Dim extStatus As String = String.Empty
            For Each item As KeyValuePair(Of esriLicenseExtensionCode, esriLicenseStatus) In m_extensionStatus
                Dim info As String = ReportInformation(licenseInfo, item.Key, item.Value)
                If Not String.IsNullOrEmpty(info) Then
                    extStatus += info + Environment.NewLine
                End If
            Next

            Dim status As String = prodStatus + extStatus
            Return status.Trim()
        End Function

        ''' <summary>
        ''' Shuts down AoInitialize object and check back in extensions to ensure
        ''' any ESRI libraries that have been used are unloaded in the correct order.
        ''' </summary>
        ''' <remarks>Once Shutdown has been called, you cannot re-initialize the product license
        ''' and should not make any ArcObjects call.</remarks>
        Public Sub ShutdownApplication()
            If m_hasShutDown Then Return

            'Check back in extensions
            For Each item As KeyValuePair(Of esriLicenseExtensionCode, esriLicenseStatus) In m_extensionStatus
                If item.Value = esriLicenseStatus.esriLicenseCheckedOut Then
                    m_AoInit.CheckInExtension(item.Key)
                End If
            Next

            m_requestedProducts.Clear()
            m_requestedExtensions.Clear()
            m_extensionStatus.Clear()
            m_productStatus.Clear()
            m_AoInit.Shutdown()
            m_hasShutDown = True
        End Sub

        ''' <summary>
        ''' Indicates if the extension is currently checked out.
        ''' </summary>    
        Public Function IsExtensionCheckedOut(ByVal code As esriLicenseExtensionCode) As Boolean
            Return m_AoInit.IsExtensionCheckedOut(code)
        End Function

        ''' <summary>
        ''' Set the extension(s) to be checked out for your ArcObjects code. 
        ''' </summary>
        Public Function AddExtensions(ByVal ParamArray requestCodes As esriLicenseExtensionCode()) As Boolean
            If m_requestedExtensions Is Nothing Then
                m_requestedExtensions = New List(Of esriLicenseExtensionCode)()
            End If

            For Each code As esriLicenseExtensionCode In requestCodes
                If Not m_requestedExtensions.Contains(code) Then
                    m_requestedExtensions.Add(code)
                End If
            Next

            If m_hasInitializeProduct Then
                Return CheckOutLicenses(Me.InitializedProduct)
            Else
                Return False
            End If
        End Function

        ''' <summary>
        ''' Check in extension(s) when it is no longer needed.
        ''' </summary>
        Public Sub RemoveExtensions(ByVal ParamArray requestCodes As esriLicenseExtensionCode())
            If m_extensionStatus Is Nothing OrElse m_extensionStatus.Count = 0 Then
                Return
            End If

            For Each code As esriLicenseExtensionCode In requestCodes
                If m_extensionStatus.ContainsKey(code) Then
                    If m_AoInit.CheckInExtension(code) = esriLicenseStatus.esriLicenseCheckedIn Then
                        m_extensionStatus(code) = esriLicenseStatus.esriLicenseCheckedIn
                    End If
                End If
            Next
        End Sub

        ''' <summary>
        ''' Get/Set the ordering of product code checking. If true, check from lowest to 
        ''' highest license. True by default.
        ''' </summary>
        Public Property InitializeLowerProductFirst() As Boolean
            Get
                Return m_productCheckOrdering
            End Get
            Set(ByVal value As Boolean)
                m_productCheckOrdering = value
            End Set
        End Property

        ''' <summary>
        ''' Retrieves the product code initialized in the ArcObjects application
        ''' </summary>
        Public ReadOnly Property InitializedProduct() As esriLicenseProductCode
            Get
                Try
                    Return m_AoInit.InitializedProduct()
                Catch
                    Return 0
                End Try
            End Get
        End Property

#Region "Helper methods"
        Private Function Initialize() As Boolean
            If m_requestedProducts Is Nothing OrElse m_requestedProducts.Count = 0 Then
                m_hasInitializeProduct = True
                Return False
            End If

            Dim currentProduct As esriLicenseProductCode = New esriLicenseProductCode
            Dim productInitialized As Boolean = False

            'Try to initialize a product
            Dim licInfo As ILicenseInformation = CType(m_AoInit, ILicenseInformation)

            m_requestedProducts.Sort()
            If Not InitializeLowerProductFirst Then 'Request license from highest to lowest
                m_requestedProducts.Reverse()
            End If

            For Each prodNumber As Integer In m_requestedProducts
                Dim prod As esriLicenseProductCode = CType(System.Enum.ToObject(GetType(esriLicenseProductCode), prodNumber), esriLicenseProductCode)
                Dim status As esriLicenseStatus = m_AoInit.IsProductCodeAvailable(prod)
                If (status = esriLicenseStatus.esriLicenseAvailable) Then
                    status = m_AoInit.Initialize(prod)
                    If (status = esriLicenseStatus.esriLicenseAlreadyInitialized Or _
                            status = esriLicenseStatus.esriLicenseCheckedOut) Then
                        productInitialized = True
                        currentProduct = m_AoInit.InitializedProduct()
                    End If
                End If

                m_productStatus.Add(prod, status)

                If productInitialized Then Exit For
            Next

            m_hasInitializeProduct = productInitialized
            m_requestedProducts.Clear()

            'No product is initialized after trying all requested licenses, quit
            If Not productInitialized Then Return False

            'Check out extension licenses
            Return CheckOutLicenses(currentProduct)
        End Function

        Private Function CheckOutLicenses(ByVal currentProduct As esriLicenseProductCode) As Boolean
            Dim allSuccessful As Boolean = True

            'Request extensions
            If m_requestedExtensions IsNot Nothing AndAlso currentProduct <> 0 Then

                For Each ext As esriLicenseExtensionCode In m_requestedExtensions
                    Dim licenseStatus As esriLicenseStatus = m_AoInit.IsExtensionCodeAvailable(currentProduct, ext)
                    If (licenseStatus = esriLicenseStatus.esriLicenseAvailable) Then 'skip unavailable extensions
                        licenseStatus = m_AoInit.CheckOutExtension(ext)
                    End If
                    allSuccessful = (allSuccessful And licenseStatus = esriLicenseStatus.esriLicenseCheckedOut)
                    If (m_extensionStatus.ContainsKey(ext)) Then
                        m_extensionStatus(ext) = licenseStatus
                    Else
                        m_extensionStatus.Add(ext, licenseStatus)
                    End If
                Next

                m_requestedExtensions.Clear()
            End If

            Return allSuccessful
        End Function

        Private Function ReportInformation(ByVal licInfo As ILicenseInformation, ByVal code As esriLicenseProductCode, ByVal status As esriLicenseStatus) As String
            Dim prodName As String = String.Empty
            Try
                prodName = licInfo.GetLicenseProductName(code)
            Catch
                prodName = code.ToString()
            End Try
            Dim statusInfo As String = String.Empty

            Select Case status
                Case esriLicenseStatus.esriLicenseAlreadyInitialized, esriLicenseStatus.esriLicenseCheckedOut
                    statusInfo = String.Format(MessageProductAvailable, prodName)
                Case Else
                    statusInfo = String.Format(MessageProductNotLicensed, prodName)
            End Select

            Return statusInfo
        End Function

        Private Function ReportInformation(ByVal licInfo As ILicenseInformation, ByVal code As esriLicenseExtensionCode, ByVal status As esriLicenseStatus) As String
            Dim extensionName As String = String.Empty
            Try
                extensionName = licInfo.GetLicenseExtensionName(code)
            Catch
                extensionName = code.ToString()
            End Try
            Dim statusInfo As String = String.Empty

            Select Case status
                Case esriLicenseStatus.esriLicenseAlreadyInitialized, esriLicenseStatus.esriLicenseCheckedOut
                    statusInfo = String.Format(MessageExtensionAvailable, extensionName)
                Case esriLicenseStatus.esriLicenseCheckedIn
                    Exit Select
                Case esriLicenseStatus.esriLicenseUnavailable
                    statusInfo = String.Format(MessageExtensionUnavailable, extensionName)
                Case esriLicenseStatus.esriLicenseFailure
                    statusInfo = String.Format(MessageExtensionFailed, extensionName)
                Case Else
                    statusInfo = String.Format(MessageExtensionNotLicensed, extensionName)
            End Select

            Return statusInfo
        End Function
#End Region
    End Class



End Namespace